package pl.un4giv3n.mightvsmagic.action;

import javax.persistence.EntityManager;

import pl.un4giv3n.mightvsmagic.entity.Action;
import pl.un4giv3n.mightvsmagic.entity.ActionType;
import pl.un4giv3n.mightvsmagic.entity.ActivityType;
import pl.un4giv3n.mightvsmagic.entity.Reward;
import pl.un4giv3n.mightvsmagic.entity.User;
import pl.un4giv3n.mightvsmagic.entity.UserActivity;
import pl.un4giv3n.mightvsmagic.entity.UserType;
import pl.un4giv3n.mightvsmagic.utils.ActionUtil;
import pl.un4giv3n.mightvsmagic.utils.ActivityLogUtil;
import pl.un4giv3n.mightvsmagic.utils.ClanUtil;

/**
 * @author andrzejewskia
 * action that increases user experience
 */
public class TrainAction extends PersistenceAction {

	private static final int TRAINING_COST = 50;
	private static final long serialVersionUID = 1L;
	/**
	 * user current action
	 */
	private Action currentAction;
	/**
	 * session user
	 */
	private User user;
	/**
	 * performed actionType
	 */
	private ActionType actionType;


	/* (non-Javadoc)
	 * @see pl.un4giv3n.mightvsmagic.action.PersistenceAction#execute()
	 */
	@Override
	public String execute() {
		EntityManager entityManager = getEntityManager();
		user = getSessionUser(entityManager);
		if (user == null) {
			addActionError("Zaloguj się");
			entityManager.close();
			return LOGIN;
		}
		currentAction = user.getCurrentAction();
		if (currentAction == null || currentAction.equals(Action.NO_ACTION)) {
			long gold = user.getGold();
			if (gold < TRAINING_COST) {
				addActionError("Nie posiadasz wystarczającej ilości złota by trenować!");
				return INPUT;
			}
			if (actionType == null) {
				addActionError("Nie wybrano typu treningu!");
				return INPUT;
			}
			startTraining(entityManager, gold);
			return ACTION_START;
		} else {
			return "redirect";
		}
	}

	private void startTraining(EntityManager entityManager, long gold) {
		entityManager.getTransaction().begin();
		long exp = calculateAdditionalExp();
		currentAction = new Action(actionType, new Reward(0,
				isFightTraining() ? exp : 0, isMagicTraining() ? exp : 0));
		user.setCurrentAction(currentAction);
		user.removeGold(TRAINING_COST);
		UserActivity activity = ActivityLogUtil.createActivity(ActivityType.TRAIN_START, user.getId());
		entityManager.persist(activity);
		entityManager.merge(user);
		entityManager.flush();
		entityManager.getTransaction().commit();
		entityManager.close();
	}

	private boolean isMagicTraining() {
		return actionType == ActionType.TRAIN_MAGIC;
	}
	
	private boolean isFightTraining() {
		return actionType == ActionType.TRAIN_FIGHT;
	}


	private long calculateAdditionalExp() {
		int factor = 6;
		if((isFightTraining() && user.getUserType() != UserType.KNIGHT) || (isMagicTraining() && user.getUserType() != UserType.MAGE)){
			factor = 2;
		}
		long result = (long)(Math.random() * factor + (isFightTraining()? user.getFightExp()/750 : user.getMagicExp()/750));
		if(user.getClan() != null && isFightTraining()){
			result+=ClanUtil.getFightExpBonus(user.getClan());
		}
		if(user.getClan() != null && isMagicTraining()){
			result+=ClanUtil.getMagicExpBonus(user.getClan());
		}
		return result;
	}

	public void setActionType(String actionType) {
		this.actionType = ActionType.valueOf(actionType);
	}
	
	public String getActionEnd(){
		return ActionUtil.generateStartMessage(currentAction, user);
	}
	
	public String getActionEndString(){
		return ActionUtil.getActionEndDate(currentAction, user);
	}

	public User getUser() {
		return user;
	}

}
